from fastapi import APIRouter, HTTPException, status, Request
from tortoise.expressions import Q
from datetime import datetime,timedelta
from application import settings
from . import scheam, models
from application.utils import wechat_tools,tools
from application.utils.jwt_tool import JwtToken

app = APIRouter()

@app.post('/register', response_model=scheam.UserInfoRegResponse)
async def register(request:Request,user_info: scheam.UserInfoRegRequest):
    """用户注册"""
    # 0. 验证数据[手机号是否重复注册，验证码]

    # 1. 基于code请求微信服务器获取用户的OpenID以及将来调用用户信息的session_key
    result = wechat_tools.get_wechat_info(user_info.code)
    # 0. 根据手机号或微信OpenID判断是否重复注册
    user = await models.User.filter(Q(mobile=user_info.mobile) | Q(openid=result['openid'])).first()
    if user:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail='当前手机号/微信号重复注册！')

    # 0. 验证码是否正确
    redis = request.app.state.redis
    sms_code = await redis.get(f'sms_{user_info.mobile}')

    if not sms_code:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail='验证码不存在或填写错误！')

    if sms_code != user_info.sms_code:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail='验证码不存在或填写错误！')

    # 在redis中删除已经使用过的验证码
    await redis.delete(f'sms_{user_info.mobile}')


    # 2. 保存数据到用户表
    user = await models.User.create(
        **dict(user_info),
        username=user_info.mobile,
        avatar=user_info.avatarUrl,
        nickname=user_info.nickName,
        sex=user_info.gender,
        openid=result['openid']
    )

    # 注册成功用户，自动登录即可，返回jwt
    token = JwtToken.create_token({
        'id': user.id,
        'username': user.username
    })

    # 3. 返回结构
    return {
        'id': user.id,
        'nickname': user.nickname,
        'avatar': user.avatar,
        'code': 200,
        'err_msg': '用户注册成功',
        'status': 'Success',
        'token': token
    }

@app.post('/login',response_model=scheam.UserInfoRegResponse)
async def login(request:Request,user_info:scheam.UserLoginRequest):
    """用户登录操作"""
    redis=request.app.state.redis
    sms_code=await redis.get(f"sms_{user_info.mobile}")

    if not sms_code:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,detail="验证码不存在或填写错误")

    if sms_code !=user_info.sms_code:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,detail="验证码不存在或填写错误")

    result=wechat_tools.get_wechat_info(user_info.code)

    user=await models.User.filter(Q(mobile=user_info.mobile) | Q(openid=result['openid'])).first()
    if not user:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,detail='当前用户不存在')

#     判断密码是否正确
    hashing=tools.Hashing()
    ret=hashing.verify(user_info.password,user.password)
    if not ret:
        raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,detail='当前账号或密码错误!')

    token=JwtToken.create_token({
        'id':user.id,
        'username':user.username
    })

    # 记录用户的登录历史
    await models.UserLoginHistory.create(user=user)

#     保存Token到redis中
    await redis.setex(f'token_{user.id}',settings.JWT['expire_time'],token)

#     如果打开限流功能，则初始化用户每天免费使用AI助理的次数到redis中，次日过期
    if settings.AI_ROBOT['limit']=='1':
        current_time=datetime.now()
        tomorrow=current_time+timedelta(days=1)
        tomorrow_zero=datetime.strptime(f"{tomorrow.year}-{tomorrow.month}-{tomorrow.day}",'%Y-%m-%d')
        delta=tomorrow_zero-current_time
        redis.setex(f"api_{user.id}",delta.seconds,settings.AI_ROBOT['count'])

#   删除短信验证码，一码多用
    await redis.delete(f"sms_{user_info.mobile}")

    return {
        'id':user.id,
        'nickname':user.nickname,
        'avatar':user.avatar,
        'code':200,
        'err_msg':"用户登录成功",
        'stasus':'Success',
        'token':token
    }


























